package com.bookstore.service.impl;

import com.bookstore.dto.OrderDTO;
import com.bookstore.dto.OrderItemDTO;
import com.bookstore.entity.Book;
import com.bookstore.entity.Order;
import com.bookstore.entity.OrderItem;
import com.bookstore.entity.User;
import com.bookstore.repository.BookRepository;
import com.bookstore.repository.OrderRepository;
import com.bookstore.repository.UserRepository;
import com.bookstore.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BookRepository bookRepository;

    @Autowired
    private BookServiceImpl bookService;

    @Override
    @Transactional
    public OrderDTO createOrder(OrderDTO orderDTO) {
        User user = userRepository.findById(orderDTO.getUserId())
                .orElseThrow(() -> new RuntimeException("User not found"));

        Order order = new Order();
        order.setUser(user);
        order.setTotalAmount(orderDTO.getTotalAmount());
        order.setStatus("待付款");
        order.setAddress(orderDTO.getAddress());
        order.setPhone(orderDTO.getPhone());
        order.setExpireTime(orderDTO.getExpireTime());
        order.setCreatedAt(LocalDateTime.now());
        
        // 生成唯一订单号
        String orderNumber = generateOrderNumber();
        order.setOrderNumber(orderNumber);

        // 先保存order，获取ID
        orderRepository.save(order);
        
        // 然后处理items
        List<OrderItem> items = orderDTO.getItems().stream()
                .map(itemDTO -> convertToOrderItem(itemDTO, order))
                .collect(Collectors.toList());
        order.setItems(items);
        
        // 再次保存order和关联的items
        orderRepository.save(order);

        OrderDTO orderDTO1 = convertToDTO(order);

        return orderDTO1;
    }

    @Override
    public ResponseEntity<List<OrderDTO>> getUserOrders(Long userId) {
        List<Order> orders = orderRepository.findByUserId(userId);
        List<OrderDTO> orderDTOs = orders.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        return ResponseEntity.ok(orderDTOs);
    }

    @Override
    public ResponseEntity<OrderDTO> getOrderById(Long orderId) {
        return orderRepository.findById(orderId)
                .map(order -> ResponseEntity.ok(convertToDTO(order)))
                .orElse(ResponseEntity.notFound().build());
    }

    @Override
    public ResponseEntity<?> deleteById(Long orderId) {
        orderRepository.deleteById(orderId);
        return ResponseEntity.ok("已删除");
    }

    @Override
    public ResponseEntity<?> payOrder(Long orderId, String paymentMethod) {
        return orderRepository.findById(orderId)
        .map(order -> {
            order.setStatus("已付款");
            order.setPaymentMethod(paymentMethod);
            orderRepository.save(order);
            return ResponseEntity.ok("订单状态更新成功");
        })
        .orElse(ResponseEntity.notFound().build());
    }

    @Override
    @Transactional
    public ResponseEntity<?> updateOrderStatus(Long orderId, String status) {
        return orderRepository.findById(orderId)
                .map(order -> {
                    order.setStatus(status);
                    orderRepository.save(order);
                    return ResponseEntity.ok("订单状态更新成功");
                })
                .orElse(ResponseEntity.notFound().build());
    }

    private OrderDTO convertToDTO(Order order) {
        OrderDTO dto = new OrderDTO();
        dto.setId(order.getId());
        dto.setUserId(order.getUser().getId());
        dto.setTotalAmount(order.getTotalAmount());
        dto.setStatus(order.getStatus());
        dto.setAddress(order.getAddress());
        dto.setPhone(order.getPhone());
        dto.setExpireTime(order.getExpireTime());
        dto.setPaymentMethod(order.getPaymentMethod());
        dto.setOrderNumber(order.getOrderNumber());
        dto.setCreatedAt(order.getCreatedAt());

        List<OrderItemDTO> itemDTOs = order.getItems().stream()
                .map(this::convertToItemDTO)
                .collect(Collectors.toList());
        dto.setItems(itemDTOs);

        return dto;
    }

    private OrderItemDTO convertToItemDTO(OrderItem item) {
        OrderItemDTO dto = new OrderItemDTO();
        dto.setId(item.getId());
        dto.setBookId(item.getBook().getId());
        dto.setQuantity(item.getQuantity());
        dto.setPrice(item.getPrice());
        dto.setBookTitle(item.getBook().getTitle());
        dto.setImageUrl(item.getBook().getImageUrl());
        dto.setBookAuthor(item.getBook().getAuthor());
        dto.setBookDegree(item.getBook().getDegree());

        dto.setBook(bookService.convertToDTO(item.getBook()));
        return dto;
    }

    private OrderItem convertToOrderItem(OrderItemDTO dto, Order order) {
        OrderItem item = new OrderItem();
        item.setOrder(order); // 恢复这一行
        item.setQuantity(dto.getQuantity());
        item.setPrice(dto.getPrice());
        
        // 需要设置book属性，否则book为null
        Book book = bookRepository.findById(dto.getBookId())
                .orElseThrow(() -> new RuntimeException("Book not found with id: " + dto.getBookId()));
        item.setBook(book);
        
        return item;
    }
    
    /**
     * 生成唯一订单号
     * 格式：年月日时分秒 + 4位随机数
     * 例如：20230615123045 + 1234 = 202306151230451234
     */
    private String generateOrderNumber() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 格式化为年月日时分秒
        String timeStr = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        
        // 生成4位随机数
        int randomNum = (int) (Math.random() * 10000);
        String randomStr = String.format("%04d", randomNum);
        
        // 组合成订单号
        return timeStr + randomStr;
    }
}